From: Keir Fraser Date: Fri, 4 Dec 2009 07:02:49 +0000 (+0000) Subject: libxenlight: fix GC when cloning contexts X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~12964 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=88de8df0dca10d6c7f8bca833f09b324216ac318;p=xen.git libxenlight: fix GC when cloning contexts Provide a function to clone a context. This is necessary because simply copying the structs will eventually corrup the GC: maxsize is updated in the cloned context but not in the originating, yet they have the same array of referenced pointers alloc_ptrs. Signed-off-by: Andres Lagar-Cavilla --- diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 10ed0e06fd..41010ef5df 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -656,10 +656,17 @@ void dm_xenstore_record_pid(struct libxl_ctx *ctx, void *for_spawn, struct libxl_device_model_starting *starting = for_spawn; struct libxl_ctx clone; char *kvs[3]; - int rc; - - clone = *ctx; - clone.xsh = xs_daemon_open(); + int rc, cloned; + + if (libxl_clone_context_xs(ctx, &clone)) { + XL_LOG(ctx, XL_LOG_ERROR, "Out of memory when cloning context"); + /* Throw a prayer fallback */ + clone = *ctx; + clone.xsh = xs_daemon_open(); + cloned = 0; + } else { + cloned = 1; + } /* we mustn't use the parent's handle in the child */ kvs[0] = "image/device-model-pid"; @@ -669,7 +676,11 @@ void dm_xenstore_record_pid(struct libxl_ctx *ctx, void *for_spawn, if (rc) XL_LOG_ERRNO(&clone, XL_LOG_ERROR, "Couldn't record device model pid %ld at %s/%s", (unsigned long)innerchild, starting->dom_path, kvs); - xs_daemon_close(clone.xsh); + if (cloned) { + libxl_discard_cloned_context_xs(&clone); + } else { + xs_daemon_close(clone.xsh); + } } static int libxl_vfb_and_vkb_from_device_model_info(struct libxl_ctx *ctx, diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index eb54d344a9..16705f3b7a 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -212,15 +212,19 @@ int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force) fd_set rfds; struct timeval tv; flexarray_t *toremove; - struct libxl_ctx clone = *ctx; + struct libxl_ctx clone; + + if (libxl_clone_context_xs(ctx, &clone)) { + XL_LOG(ctx, XL_LOG_ERROR, "Out of memory when cloning context"); + return ERROR_NOMEM; + } - clone.xsh = xs_daemon_open(); toremove = flexarray_make(16, 1); path = libxl_sprintf(&clone, "/local/domain/%d/device", domid); l1 = libxl_xs_directory(&clone, XBT_NULL, path, &num1); if (!l1) { XL_LOG(&clone, XL_LOG_ERROR, "%s is empty", path); - xs_daemon_close(clone.xsh); + libxl_discard_cloned_context_xs(&clone); return -1; } for (i = 0; i < num1; i++) { @@ -269,7 +273,7 @@ int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force) xs_rm(clone.xsh, XBT_NULL, path); } flexarray_free(toremove); - xs_daemon_close(clone.xsh); + libxl_discard_cloned_context_xs(&clone); return 0; } diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c index a04ac8ddf7..eeadbfd71f 100644 --- a/tools/libxl/libxl_internal.c +++ b/tools/libxl/libxl_internal.c @@ -28,6 +28,28 @@ int libxl_error_set(struct libxl_ctx *ctx, int code) return 0; } +int libxl_clone_context(struct libxl_ctx *from, struct libxl_ctx *to) +{ + /* We could just copy the structs, but since + * maxsize is not a pointer we need to take care + * of our own GC. */ + *to = *from; + to->alloc_ptrs = NULL; + to->alloc_maxsize = 256; + to->alloc_ptrs = calloc(to->alloc_maxsize, sizeof(void *)); + if (!to->alloc_ptrs) + return ERROR_NOMEM; + return 0; +} + +void libxl_discard_cloned_context(struct libxl_ctx *ctx) +{ + /* We only need to worry about GC-related fields */ + (void)libxl_ctx_free(ctx); + if (ctx->alloc_ptrs) + free(ctx->alloc_ptrs); +} + int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr) { int i; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index a08821be34..6aa98cae64 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -63,6 +63,23 @@ typedef struct { #define PRINTF_ATTRIBUTE(x, y) __attribute__((format(printf, x, y))) /* memory allocation tracking/helpers */ +int libxl_clone_context(struct libxl_ctx *from, struct libxl_ctx *to); +static inline int libxl_clone_context_xs( + struct libxl_ctx *from, struct libxl_ctx *to) +{ + int rc; + rc = libxl_clone_context(from, to); + if (rc) return rc; + to->xsh = xs_daemon_open(); + return 0; +} +void libxl_discard_cloned_context(struct libxl_ctx *ctx); +static inline void libxl_discard_cloned_context_xs( + struct libxl_ctx *ctx) +{ + libxl_discard_cloned_context(ctx); + xs_daemon_close(ctx->xsh); +} int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr); int libxl_free(struct libxl_ctx *ctx, void *ptr); int libxl_free_all(struct libxl_ctx *ctx);